import type { McpServer, ThreadMcpServer } from "@shared/triplit/types";

type ThreadMcpServerWithServer = ThreadMcpServer & {
  mcpServer?: McpServer;
};

import { threadMcpServersQueries } from "../definitions/thread-mcp-servers-queries";
import type { QueryConfig, QueryOneConfig, QueryResult } from "../types";
import { useStandardQuery, useStandardQueryOne } from "./use-standard-query";

/**
 * Get all thread-MCP server associations
 */
export function useThreadMcpServers(
  config?: QueryConfig<"threadMcpServers">,
): QueryResult<ThreadMcpServer[]> {
  return useStandardQuery(threadMcpServersQueries.all, config);
}

/**
 * Get thread-MCP server associations by thread ID
 */
export function useThreadMcpServersByThreadId(
  threadId: string,
  config?: QueryConfig<"threadMcpServers">,
): QueryResult<ThreadMcpServer[]> {
  return useStandardQuery(
    () => {
      if (!threadId) {
        return threadMcpServersQueries.byThreadId("__nonexistent__");
      }
      return threadMcpServersQueries.byThreadId(threadId);
    },
    {
      ...config,
      enabled: !!threadId && config?.enabled !== false,
    },
  );
}

/**
 * Get enabled thread-MCP server associations by thread ID
 */
export function useEnabledThreadMcpServersByThreadId(
  threadId: string,
  config?: QueryConfig<"threadMcpServers">,
): QueryResult<ThreadMcpServer[]> {
  return useStandardQuery(
    () => {
      if (!threadId) {
        return threadMcpServersQueries.enabledByThreadId("__nonexistent__");
      }
      return threadMcpServersQueries.enabledByThreadId(threadId);
    },
    {
      ...config,
      enabled: !!threadId && config?.enabled !== false,
    },
  );
}

/**
 * Get MCP servers associated with a thread (with server details)
 */
export function useMcpServersByThreadId(
  threadId: string,
  config?: QueryConfig<"threadMcpServers">,
): QueryResult<McpServer[]> {
  const result = useStandardQuery(
    () => {
      if (!threadId) {
        return threadMcpServersQueries.withServersByThreadId("__nonexistent__");
      }
      return threadMcpServersQueries.withServersByThreadId(threadId);
    },
    {
      enabled: !!threadId && config?.enabled !== false,
    },
  );

  return {
    ...result,
    data:
      result.data
        ?.map((association: ThreadMcpServerWithServer) => association.mcpServer)
        .filter((server: McpServer | undefined): server is McpServer =>
          Boolean(server),
        ) ?? [],
  };
}

/**
 * Get enabled MCP servers associated with a thread (with server details)
 */
export function useEnabledMcpServersByThreadId(
  threadId: string,
  config?: QueryConfig<"threadMcpServers">,
): QueryResult<McpServer[]> {
  const result = useStandardQuery(
    () => {
      if (!threadId) {
        return threadMcpServersQueries.enabledWithServersByThreadId(
          "__nonexistent__",
        );
      }
      return threadMcpServersQueries.enabledWithServersByThreadId(threadId);
    },
    {
      enabled: !!threadId && config?.enabled !== false,
    },
  );

  return {
    ...result,
    data:
      result.data
        ?.map((association: ThreadMcpServerWithServer) => association.mcpServer)
        .filter((server: McpServer | undefined): server is McpServer =>
          Boolean(server),
        ) ?? [],
  };
}

/**
 * Get thread-MCP server associations by MCP server ID
 */
export function useThreadMcpServersByMcpServerId(
  mcpServerId: string,
  config?: QueryConfig<"threadMcpServers">,
): QueryResult<ThreadMcpServer[]> {
  return useStandardQuery(
    () => {
      if (!mcpServerId) {
        return threadMcpServersQueries.byMcpServerId("__nonexistent__");
      }
      return threadMcpServersQueries.byMcpServerId(mcpServerId);
    },
    {
      ...config,
      enabled: !!mcpServerId && config?.enabled !== false,
    },
  );
}

/**
 * Check if a specific MCP server is associated with a thread
 */
export function useIsServerAssociatedWithThread(
  threadId: string,
  mcpServerId: string,
  config?: QueryConfig<"threadMcpServers">,
): QueryResult<boolean> {
  const result = useStandardQuery(
    () => {
      if (!threadId || !mcpServerId) {
        return threadMcpServersQueries.byThreadIdAndServerId(
          "__nonexistent__",
          "__nonexistent__",
        );
      }
      return threadMcpServersQueries.byThreadIdAndServerId(
        threadId,
        mcpServerId,
      );
    },
    {
      enabled: !!threadId && !!mcpServerId && config?.enabled !== false,
    },
  );

  return {
    ...result,
    data: (result.data?.length ?? 0) > 0,
  };
}

/**
 * Check if a specific MCP server is enabled for a thread
 */
export function useIsServerEnabledForThread(
  threadId: string,
  mcpServerId: string,
  config?: QueryConfig<"threadMcpServers">,
): QueryResult<boolean> {
  const result = useStandardQuery(
    () => {
      if (!threadId || !mcpServerId) {
        return threadMcpServersQueries.enabledByThreadIdAndServerId(
          "__nonexistent__",
          "__nonexistent__",
        );
      }
      return threadMcpServersQueries.enabledByThreadIdAndServerId(
        threadId,
        mcpServerId,
      );
    },
    {
      enabled: !!threadId && !!mcpServerId && config?.enabled !== false,
    },
  );

  return {
    ...result,
    data: (result.data?.length ?? 0) > 0,
  };
}

/**
 * Get a single thread-MCP server association
 */
export function useThreadMcpServer(
  threadId: string,
  mcpServerId: string,
  config?: QueryOneConfig<"threadMcpServers">,
): QueryResult<ThreadMcpServer | null> {
  return useStandardQueryOne(
    () => {
      if (!threadId || !mcpServerId) {
        return threadMcpServersQueries.byThreadIdAndServerId(
          "__nonexistent__",
          "__nonexistent__",
        );
      }
      return threadMcpServersQueries.byThreadIdAndServerId(
        threadId,
        mcpServerId,
      );
    },
    {
      ...config,
      enabled: !!threadId && !!mcpServerId && config?.enabled !== false,
    },
  );
}
